﻿#include "CameraFluo.h"


namespace Qly {

inline double scaleFromStandardRange(double min, double max, double value)
{
    return min + (value + 1) * (max - min) / 2.0;
}

inline double scaleToStandardRange(double min, double max, double value)
{
    return -1.0 + 2.0 *  (value - min) / (max - min);
}

bool CameraFluoImageProcessing::whiteBalanceMode(WhiteBalanceMode &mode)
{
    mode = WhiteBalanceManual;
    return true;
}

bool CameraFluoImageProcessing::setManualWhiteBalance(double colorTemperature, double Tint)
{
    if (m_hDevHandle == nullptr)
    {
         return false;
    }
    int nRet = Fluocam_put_TempTint(m_hDevHandle, colorTemperature, Tint);
    return nRet >= 0;
}

bool CameraFluoImageProcessing::manualWhiteBalance(double &colorTemperature, double &Tint)
{
    int temp, tint;
    if (m_hDevHandle == nullptr)
    {
         return false;
    }
    int nRet = Fluocam_get_TempTint(m_hDevHandle, &temp, &tint);
    if(nRet >= 0 )
    {
        colorTemperature = temp;
        Tint = tint;
    }
    return nRet >= 0;
}

bool CameraFluoImageProcessing::setWhiteBalance(int red, int green, int blue)
{
    int aGain[3];
    if (m_hDevHandle == nullptr)
    {
         return false;
    }
    aGain[0] = red;
    aGain[1] = green;
    aGain[2] = blue;
    int nRet = Fluocam_put_WhiteBalanceGain(m_hDevHandle, aGain);
    return nRet >= 0;
}

bool CameraFluoImageProcessing::whiteBalance(int &red, int &green, int &blue)
{
    int aGain[3];
    if (m_hDevHandle == nullptr)
    {
         return false;
    }
    int nRet = Fluocam_get_WhiteBalanceGain(m_hDevHandle, aGain);
    if(nRet >= 0)
    {
        red = aGain[0];
        green = aGain[1];
        blue = aGain[2];
    }
    return nRet >= 0;
}

bool CameraFluoImageProcessing::setWhiteBalanceMode(WhiteBalanceMode mode)
{
    if (m_hDevHandle == nullptr)
    {
         return false;
    }
    int nRet = -1;
    switch (mode) {
    case WhiteBalanceManual:

        break;
    case WhiteBalanceAutoOnePush:
        nRet = Fluocam_AwbOnce(m_hDevHandle, nullptr, nullptr);
        break;
    case WhiteBalanceAutoContinuous:

        break;
    }
    return nRet >= 0;
}


bool CameraFluoImageProcessing::whiteBalanceTempRange(int &nMin, int &nMax, int &nValue)
{
    if (nullptr == m_hDevHandle)
    {
         return false;
    }
    nMin = FLUOCAM_TEMP_MIN;
    nMax = FLUOCAM_TEMP_MAX;
    int v;
    int nRet = Fluocam_get_TempTint(m_hDevHandle, &nValue, &v);
    return nRet >= 0;
}

bool CameraFluoImageProcessing::whiteBalanceTintRange(int &nMin, int &nMax, int &nValue)
{
    if (nullptr == m_hDevHandle)
    {
         return false;
    }
    nMin = FLUOCAM_TINT_MIN;
    nMax = FLUOCAM_TINT_MAX;
    int v;
    int nRet = Fluocam_get_TempTint(m_hDevHandle, &v, &nValue);
    return nRet >= 0;
}

bool CameraFluoImageProcessing::setWhiteBalanceTempTint(int temp, int tint)
{
    if (nullptr == m_hDevHandle)
    {
         return false;
    }
    int nRet = Fluocam_put_TempTint(m_hDevHandle, temp, tint);
    return nRet >= 0;
}

bool CameraFluoImageProcessing::whiteBalanceTempTint(int &temp, int &tint)
{
    if (nullptr == m_hDevHandle)
    {
         return false;
    }
    int nRet = Fluocam_get_TempTint(m_hDevHandle, &temp, &tint);
    return nRet >= 0;
}


bool CameraFluoImageProcessing::setGain(double fValue)
{
    if(m_hDevHandle == nullptr)
    {
        return false;
    }
    unsigned short AGain = static_cast<unsigned short>(fValue);
    int nRet = Fluocam_put_ExpoAGain(m_hDevHandle, AGain);
    if (nRet < 0)
    {
        qWarning() << "error: Set Gain fail, AGain = "  << AGain;
        return false;
    }
    return true;
}

bool CameraFluoImageProcessing::gainMode(GainMode &mode)
{
//Fluocam_get_AutoExpoEnable
    return false;
}

bool CameraFluoImageProcessing::setGainMode(GainMode mode)
{
    if(m_hDevHandle == nullptr)
    {
        return false;
    }
    switch (mode) {
    case GainManual:
        break;
    case GainAutoOnePush:
        break;
    case GainAutoContinuous:
        break;
    }
    return false;
}

bool CameraFluoImageProcessing::brightnessEnable(bool &on)
{
    on = true;
    return true;
}

bool CameraFluoImageProcessing::setBrightnessEnable(bool on)
{
    return on;
}

bool CameraFluoImageProcessing::setBrightness(double value)
{
    //qDebug() << "FLUOCAM_BRIGHTNESS_MIN = " << FLUOCAM_BRIGHTNESS_MIN << ", FLUOCAM_BRIGHTNESS_MAX = " << FLUOCAM_BRIGHTNESS_MAX;
    int nValue = scaleFromStandardRange(FLUOCAM_BRIGHTNESS_MIN, FLUOCAM_BRIGHTNESS_MAX, value);
    //qDebug() << "value = " << value << ", nValue = " << nValue;
    int nRet = Fluocam_put_Brightness(m_hDevHandle, nValue);
    if (nRet < 0)
    {
        qDebug() << "error: SetBrightness fail";
        return false;
    }
    return true;
}

bool CameraFluoImageProcessing::brightness(double &value)
{
    int min, max, nValue;
    if(brightnessRange(min, max, nValue))
    {
        value = scaleToStandardRange(min, max, nValue);
        return true;
    }
    return false;
}

bool CameraFluoImageProcessing::brightnessRange(int &nMin, int &nMax, int &nValue)
{
    if (m_hDevHandle == nullptr)
    {
         return false;
    }
    int ret, value;
    ret = Fluocam_get_Brightness(m_hDevHandle, &value);
    nMin = FLUOCAM_BRIGHTNESS_MIN;
    nMax = FLUOCAM_BRIGHTNESS_MAX;
    nValue = value;
    return ret >= 0;
}

bool CameraFluoImageProcessing::hue(double &value)
{
    int min, max, nValue;
    if(hueRange(min, max, nValue))
    {
        value = scaleToStandardRange(min, max, nValue);
        return true;
    }
    return false;
}


bool CameraFluoImageProcessing::setHue(double value)
{
    if(m_hDevHandle == nullptr)
    {
        return false;
    }
    int nValue = scaleFromStandardRange(FLUOCAM_HUE_MIN, FLUOCAM_HUE_MAX, value);
    int nRet = Fluocam_put_Hue(m_hDevHandle, nValue);
    if (nRet < 0)
    {
        qWarning() << "error: Set Hue fail";
        return false;
    }
    return true;
}

bool CameraFluoImageProcessing::hueEnable(bool &on)
{
    on = true;
    return true;
}

bool CameraFluoImageProcessing::setHueEnable(bool on)
{
    if(!on) Fluocam_put_Hue(m_hDevHandle, FLUOCAM_HUE_DEF);
    return true;
}


bool CameraFluoImageProcessing::saturationEnable(bool &on)
{
    on = true;
    return true;
}

bool CameraFluoImageProcessing::setSaturationEnable(bool on)
{
    if(!on) Fluocam_put_Saturation(m_hDevHandle, FLUOCAM_SATURATION_DEF);
    return true;
}

bool CameraFluoImageProcessing::contrastEnable(bool &on)
{
    on = true;
    return true;
}

bool CameraFluoImageProcessing::setContrastEnable(bool on)
{
    return on;
}

bool CameraFluoImageProcessing::gammaEnable(bool &on)
{
    on = true;
    return true;
}

bool CameraFluoImageProcessing::setGammaEnable(bool on)
{
    return on;
}

bool CameraFluoImageProcessing::gammaRange(double &min, double &max, double &fValue)
{
    if (m_hDevHandle == nullptr)
    {
         return false;
    }
    //获取相机Gamma值
    int gamma, ret;
    ret = Fluocam_get_Gamma(m_hDevHandle, &gamma);
    min = FLUOCAM_GAMMA_MIN;
    max = FLUOCAM_GAMMA_MAX;
    fValue = gamma;
    return ret >= 0;
}

bool CameraFluoImageProcessing::hueRange(int &nMin, int &nMax, int &nValue)
{
    if (m_hDevHandle == nullptr)
    {
         return false;
    }
    int ret, value;
    ret = Fluocam_get_Hue(m_hDevHandle, &value);
    nMin = FLUOCAM_HUE_MIN;
    nMax = FLUOCAM_HUE_MAX;
    nValue = value;
    return ret >= 0;
}

bool CameraFluoImageProcessing::gain(double &fValue)
{
    double min, max;
    return gainRange(min, max, fValue);
}

bool CameraFluoImageProcessing::gainRange(double &fMin, double &fMax, double &fValue)
{
    if (m_hDevHandle == nullptr)
    {
         return false;
    }

    unsigned short nMin;
    unsigned short nMax;
    unsigned short nDef;

    int nRet = Fluocam_get_ExpoAGainRange(m_hDevHandle, &nMin, &nMax, &nDef);
    nRet = Fluocam_get_ExpoAGain(m_hDevHandle, &nDef);

    if (nRet < 0)
    {
        qWarning() << "error: GetGainRange fail";
        return false;
    }

    fMin = nMin;
    fMax = nMax;
    fValue= nDef;
    return true;

}

bool CameraFluoImageProcessing::contrastRange(int &nMin, int &nMax, int &nValue)
{
    if (m_hDevHandle == nullptr)
    {
         return false;
    }
    int ret, value;
    ret = Fluocam_get_Contrast(m_hDevHandle, &value);
    nMin = FLUOCAM_CONTRAST_MIN;
    nMax = FLUOCAM_CONTRAST_MAX;
    nValue = value;
    return ret >= 0;
}

bool CameraFluoImageProcessing::contrast(double &value)
{
    int min, max, nValue;
    if(contrastRange(min, max, nValue))
    {
        value = scaleToStandardRange(min, max, nValue);
        return true;
    }
    return false;
}

bool CameraFluoImageProcessing::setContrast(double value)
{
    if(m_hDevHandle == nullptr)
    {
        return false;
    }
    int nValue = scaleFromStandardRange(FLUOCAM_CONTRAST_MIN, FLUOCAM_CONTRAST_MAX, value);
    int nRet = Fluocam_put_Contrast(m_hDevHandle, nValue);
    if (nRet < 0)
    {
        qWarning() << "error: Set Contrast fail";
        return false;
    }
    return true;
}

bool CameraFluoImageProcessing::saturation(double &value)
{
    int min, max, nValue;
    if(saturationRange(min, max, nValue))
    {
        value = scaleToStandardRange(min, max, nValue);
        return true;
    }
    return false;
}

bool CameraFluoImageProcessing::saturationRange(int &nMin, int &nMax, int &nValue)
{
    if (m_hDevHandle == nullptr)
    {
         return false;
    }
    int ret, value;
    ret = Fluocam_get_Saturation(m_hDevHandle, &value);
    nMin = FLUOCAM_SATURATION_MIN;
    nMax = FLUOCAM_SATURATION_MAX;
    nValue = value;
    return ret >= 0;
}

bool CameraFluoImageProcessing::setSaturation(double value)
{
    if(m_hDevHandle == nullptr)
    {
        return false;
    }

    int nValue = scaleFromStandardRange(FLUOCAM_SATURATION_MIN, FLUOCAM_SATURATION_MAX, value);
    int nRet = Fluocam_put_Saturation(m_hDevHandle, nValue);
    if (nRet < 0)
    {
        qWarning() << "error: Set Saturation fail";
        return false;
    }
    return true;
}

bool CameraFluoImageProcessing::gamma(double &v)
{
    double min, max;
//	Fluocam_get_Gamma();
    return gammaRange(min, max, v);
}

bool CameraFluoImageProcessing::setGamma(double v)
{
    if(m_hDevHandle == nullptr)
    {
        return false;
    }
    int value = static_cast<int>(v);
    int nRet = Fluocam_put_Gamma(m_hDevHandle, value);
    if (nRet < 0)
    {
        qWarning() << "error: Set Gamma fail";
        return false;
    }
    return true;
}
}


